package Variabilize;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;

import com.*;
import com.Clause.Clause;
import com.Clause.ClauseBuilder;
import com.Comparaisons.ArbreComparaisons;
import com.DB.DBConnector;
import com.DB.DBCounter;

public class Variabilize {

	private DBConnector db= null;

	private Graphe graphe = null;

	public Variabilize(DBConnector connector, Graphe graphe){
		this.graphe = graphe;
		this.db = connector;
	}

	public ArrayList<Clause> execute(){

		ArrayList<Chemin> chemins = new ArrayList<Chemin>(); 

		for(Node node : graphe.getNoeuds()){
			if(!node.getModele().isNegative()){ //clause de horn 1er non négatif	
				chemins.addAll(chercherChemins(node));
			}
		}

		ArrayList<Clause> clauses = new ArrayList<Clause>();
		
		for(Chemin chemin : chemins){
			Clause clause = ClauseBuilder.newClause(chemin);
			clauses.add(clause);
			//System.out.println(chemin+"              "+clause+"         ");
		}
		
		return clauses;
	}

	public ArrayList<Chemin> chercherChemins(Chemin src, char lettre, Node node , LinkedList<Modele> deja_parcouru){
		
		ArrayList<Chemin> chemins = new ArrayList<Chemin>();

		DBCounter counter = new DBCounter(db);

		for(Link link : node.getLinks()){
			for(ArbreComparaisons arbre : link.getArbreComparaisons()){

				if(link.getModeleDest().isNegative()){ //les autres sont negatives

					if(!deja_parcouru.contains(link.getModeleDest())){

						ArrayList<Chemin> chemins_tmp = new ArrayList<Chemin>();

						Chemin chemin;
						char lettre_aux = lettre;

						if(src == null){ //1er
							chemin = new Chemin(link.getModeleSource(),arbre.getNoeud(),link.getModeleDest());
							chemin.setVarModele1(arbre.getNoeud().getN0(),lettre_aux);
							chemin.setVarModele2(arbre.getNoeud().getN1(),lettre_aux);
							
							++lettre;

							chemins_tmp.add(chemin);

							for(ArbreComparaisons arbre_aux : arbre.getBranches()){
								chemins_tmp.addAll(chercher_suite_comparaisons(chemin,link,arbre_aux,lettre));
							}
						}

						else{ //(src != null){		

							chemin = new Chemin(src,link.getModeleSource(),arbre.getNoeud(),link.getModeleDest());

							if(src.getLettreModele2(arbre.getNoeud().getN0()) != Chemin.VIDE){
								lettre_aux = src.getLettreModele2(arbre.getNoeud().getN0());
							}
							else 
								lettre_aux = lettre++;
							
							src.setVarModele2(arbre.getNoeud().getN0(),lettre_aux);
							chemin.setVarModele2(arbre.getNoeud().getN1(),lettre_aux);

						//	System.err.println(chemin+"   "+lettre_aux);
							chemins_tmp.add(chemin);

							for(ArbreComparaisons arbre_aux : arbre.getBranches()){
								chemins_tmp.addAll(chercher_suite_comparaisons(chemin,link,arbre_aux,lettre));
							}

						}			

						//System.out.println("CHEMINS :"+chemins_tmp+"    "+chemins_tmp.size());

						for(Chemin ch : chemins_tmp){
							//System.out.println(chemins_tmp.size()+"  "+i+"---- :"+ch);

							int count = counter.count(ch .getListe());
							if(count > 0){

								deja_parcouru.addLast(link.getModeleDest());

								chemins.add(ch);
								chemins.addAll(chercherChemins(ch ,lettre,graphe.getNoeud(link.getModeleDest()),deja_parcouru));

							}
						}

					}

				}
			}
		}

		return chemins;
	}

	private Collection<Chemin> chercher_suite_comparaisons(
			Chemin chemin_src, Link link, ArbreComparaisons arbre, char lettre) {

		ArrayList<Chemin> chemins = new ArrayList<Chemin>();

		Chemin chemin = chemin_src.copie();
		chemin.addComparaison(arbre.getNoeud());
		char lettre_aux = lettre;

		if(chemin.getLettreModele1(arbre.getNoeud().getN0()) != Chemin.VIDE){
			lettre_aux = chemin.getLettreModele1(arbre.getNoeud().getN0());
		}
		else if(chemin.getLettreModele2(arbre.getNoeud().getN1()) != Chemin.VIDE){
			lettre_aux = chemin.getLettreModele2(arbre.getNoeud().getN1());
		}
		else
			lettre_aux=++lettre;

		chemin.setVarModele1(arbre.getNoeud().getN0(),lettre_aux);
		chemin.setVarModele2(arbre.getNoeud().getN1(),lettre_aux);

		chemins.add(chemin);

		for(ArbreComparaisons arbre_aux : arbre.getBranches()){
			chemins.addAll(chercher_suite_comparaisons(chemin,link,arbre_aux,lettre));
		}

		return chemins;
	}

	public ArrayList<Chemin> chercherChemins(Node node) { //que clause binaires

		ArrayList<Chemin> chemins = new ArrayList<Chemin>();

		chemins.addAll(chercherChemins(null, 'A', node , new LinkedList<Modele>()));

		return chemins;
	}



	/**
	 * 		Chemin chemin;
						char lettre_aux = lettre;

						if(src != null){
							if(arbre.getNoeud().getN0() == src.getComparaison().getN1())
								lettre_aux = src.getLettre();
							else
								lettre_aux = lettre++;
						}


						if(src == null) //1er
							chemin = new Chemin(link.getModeleSource(),arbre.getNoeud(),link.getModeleDest(),lettre_aux);
						else
							chemin = new Chemin(src,link.getModeleSource(),arbre.getNoeud(),link.getModeleDest(),lettre_aux);

						int count = counter.count(chemin.getListe());
						if(count > 0){

						//	deja_parcouru.addLast(link.getModeleSource());
							deja_parcouru.addLast(link.getModeleDest());

							chemins.addAll(chercherChemins(chemin,lettre,graphe.getNoeud(link.getModeleDest()),deja_parcouru));

							chemins.add(chemin);

						}
					}
	 */

}
